package jdk8feature.stream;

import lombok.AllArgsConstructor;
import lombok.Data;
import org.junit.jupiter.api.Test;


import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class StreamExample {

    /**
     * 初始化集合
     */
    List<MMM> mm = new ArrayList<>(Arrays.asList(
            new MMM("123"),
            new MMM("337"),
            new MMM("669")
    ));

    /**
     * 遍历
     */
    @Test
    public void outputTest() {
        List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
        System.out.println("串行");
        integers.forEach(System.out::print);
        System.out.println();
        integers.stream().forEach(System.out::print);
        System.out.println("\n并行");
        integers.parallelStream().forEach(System.out::print);


    }

    /**
     * 映射
     */
    @Test
    public void mapTest() {
        List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
        //映每个元素操作
        List<Integer> collect = integers.stream().map(n -> n * n).collect(Collectors.toList());
        System.out.println(collect);

        List<String> mms = mm.stream().map(obj -> obj.name = obj.name.concat("@@_@@")).collect(Collectors.toList());
        System.out.println(mms);
    }
    @Test
    public void collectorsTest() {
      List<MMM2> list =new ArrayList<>();
      list.add(new MMM2(1,"a",true));
      list.add(new MMM2(11,"b",false));
      list.add(new MMM2(13,"v",false));
      list.add(new MMM2(1,"d",true));
      //分组
        Map<Integer, List<MMM2>> collect = list.stream().collect(Collectors.groupingBy(MMM2::getAge));
        System.out.println(collect);
        //toMap 分组
        Map<String, List<MMM2>> collect1 = list.stream().collect(Collectors.toMap(e -> "sex:" + (e.gender ? "男" : "女"), e -> Arrays.asList(e), (e1, e2) -> {
            ArrayList<MMM2> arrayList = new ArrayList<>(e1);
            arrayList.addAll(e2);
            return arrayList;
        }));
        System.out.println(collect1);
        //分组记数
        Map<String, Long> collect2 = list.stream().collect(Collectors.groupingBy((e) -> e.isGender() ? "男" : "女", Collectors.counting()));
        System.out.println(collect2);
        //sort
        list.stream().sorted(
                Comparator.comparing(MMM2::getAge
                        , Comparator.nullsFirst(Integer::compareTo))
                        .thenComparing(MMM2::getName,Comparator.nullsFirst(String::compareTo).reversed()))
                .forEach(System.out::println);


    }
    @Test
    public void peekTest() {

//        intermediate and terminal operations
        List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
        //映每个元素操作
        List<Integer> collect = integers.stream().peek(integer -> integer= Integer.valueOf(integer+"")).collect(Collectors.toList());
        List<Integer> collect2 = integers.stream()
                .map(integer -> {
            System.out.println("map:"+integer);
            return  integer+1;
        }).peek((t)->{
                    System.out.println("peek:"+t);
                })
                .collect(Collectors.toList());
        System.out.println(collect);
        System.out.println(collect2);

    }

    /**
     * 排序、过滤、限制
     */
    @Test
    public void filterTest() {
        List<Integer> integers = Arrays.asList(9,6,5,11,2,1);
        List<Integer> collect = integers.stream()
                //.sorted()//排序
                .sorted((x, y) -> y - x)
                .distinct()//去重
                .filter(n -> n < 6)//小于6的数
                .limit(3)//只截取3个元素
                .collect(Collectors.toList());
        System.out.println(collect);
    }

    /**
     * 聚合和统计
     */
    @Test
    public void mergeTest() {
        List<String> strings = Arrays.asList("nice", " 2 ", "mmm", "!");
        String collect = strings.stream().collect(Collectors.joining(""));
        System.out.println(collect);

        List<Integer> numbers = Arrays.asList(1, 2, 71, 3, 7, 3, 5);
        stats(numbers);
    }


    public static void stats(List<Integer> numbers) {
        IntSummaryStatistics stats = numbers.stream().mapToInt((x) -> x).summaryStatistics();

        System.out.println("列表中最大的数 : " + stats.getMax());
        System.out.println("列表中最小的数 : " + stats.getMin());
        System.out.println("所有数之和 : " + stats.getSum());
        System.out.println("平均数 : " + stats.getAverage());
    }

}

@AllArgsConstructor
@Data
class MMM {

    String name;

}

@AllArgsConstructor
@Data
class MMM2 {
    Integer age;

    String name;

    boolean gender;

}


